
"""
To check if an NTP server is openly accessible from the Internet and has the 'monlist' feature enabled, you can use 'ntpdc' like this:

# ntpdc -n -c monlist 192.168.45.67
An NTP server with the 'monlist' feature enabled will return a list of clients that recently queried the NTP server:

remote address          port local address      count m ver rstr avgint  lstint

===============================================================================

123.56.67.89             123 192.168.45.67       3559 4 4      0    446     119

34.56.78.90              123 192.168.45.67      16992 4 4      0    137     207

98.76.54.32              123 192.168.45.67      17005 4 4      0    137     232

111.22.33.44           58708 192.168.45.67          3 3 4      0 423826   72192

222.33.44.55           35560 192.168.45.67          8 3 4      0 180029  236607

33.44.55.66            59053 192.168.45.67          1 3 3      0 615565  615565

44.55.66.77            59040 192.168.45.67          2 3 4      0 637297  664374
If the list of clients is currently empty, it will instead return:

***Server reports data not found
If there is no openly accessible NTP server with the 'monlist' feature enabled, the request will run into a timeout: Timeout:

192.168.45.67: timed out, nothing received

***Request timed out
"""
from scapy.all import *
import threading as thread
#Raw packet data used to request Monlist from NTP server
rawData = "\x17\x00\x03\x2a" + "\x00" * 61
#File containing all IP addresses with NTP port open.
logfile = open('ntp_ip.txt', 'r')
#Output file used to store all monlist enabled servers
outputFile = open('monlistServers.txt', 'a')
def sniffer():
    #Sniffs incomming network traffic on UDP port 48769, all packets meeting thease requirements run through the analyser function.
    sniffedPacket = sniff(filter="udp port 48769", store=0, prn=analyser)

def analyser(packet):
    #If the server responds to the GET_MONLIST command.
    if len(packet) > 200:
        if packet.haslayer(IP):
            print(packet.getlayer(IP).src)
            #Outputs the IP address to a log file.
            outputFile.write(packet.getlayer(IP).src + '\n')

thread_sniffer = thread.Thread(target=sniffer)
thread_sniffer.daemon = True
thread_sniffer.start()
for address in logfile.readlines():
    #Creates a UDP packet with NTP port 123 as the destination and the MON_GETLIST payload.
    pkg = IP(dst=address.strip())/UDP(sport=48769, dport=123)/Raw(load=rawData)
    send(pkg)
print ('End')
